package com.example.mh_flutter_amap_search

import com.amap.api.services.core.PoiItem
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeResult
import com.amap.api.services.help.Inputtips
import com.amap.api.services.help.Tip
import com.amap.api.services.poisearch.PoiResult
import com.amap.api.services.poisearch.PoiSearch
import com.amap.api.services.route.DistanceResult
import com.amap.api.services.route.DistanceSearch
import io.flutter.plugin.common.MethodChannel

class AmapCallbackHandler(private val requestType: String, private val channel: MethodChannel) : PoiSearch.OnPoiSearchListener, Inputtips.InputtipsListener,
    GeocodeSearch.OnGeocodeSearchListener,DistanceSearch.OnDistanceSearchListener{


    override fun onPoiSearched(item: PoiResult?, p1: Int){
        if (item == null){
            val map = mutableMapOf<String, Any>()
            map["requestType"] = requestType
            map["errMessage"] = "unknown err"
            channel.invokeMethod("onAMapSearchRequest_didFailWithError", map)
        }else {
            val map = mutableMapOf<String, Any>()
            val list = item.pois.map {
                mutableMapOf<String, Any>().apply {
                    this["address"] = it.snippet
                    this["adCode"] = it.adCode
                    this["title"] = it.title
                    this["cityName"] = it.cityName
                    this["cityCode"] = it.cityCode
                    this["province"] = it.provinceName
                    this["provinceCode"] = it.provinceCode
                    this["tel"] = it.tel
                    this["poiId"] = it.poiId
                    this["businessArea"] = it.businessArea
                    this["distance"] = it.distance
                    this["adName"] = it.adName
                    this["latitude"] =it.latLonPoint.latitude
                    this["longitude"] = it.latLonPoint.longitude
                }
            }

            map["requestType"] = requestType
            map["count"] = p1
            map["pois"] = list
            channel.invokeMethod("onPOISearchDone", map)
        }
    }

    override fun onPoiItemSearched(item: PoiItem?, p1: Int) {
        if (item == null){
            val map = mutableMapOf<String, Any>()
            map["requestType"] = requestType
            map["errMessage"] = "unknown err"
            channel.invokeMethod("onAMapSearchRequest_didFailWithError", map)
        }else {
            val map = mutableMapOf<String, Any>()
            val itemMap = mutableMapOf<String, Any>().apply {
                    this["address"] = item.snippet
                    this["adCode"] = item.adCode
                    this["title"] = item.title
                    this["cityName"] = item.cityName
                    this["cityCode"] = item.cityCode
                    this["province"] = item.provinceName
                    this["provinceCode"] = item.provinceCode
                    this["tel"] = item.tel
                    this["poiId"] = item.poiId
                    this["businessArea"] = item.businessArea
                    this["distance"] = item.distance
                    this["adName"] = item.adName
                    this["latitude"] =item.latLonPoint.latitude
                    this["longitude"] = item.latLonPoint.longitude
                }
            val list = mutableListOf(itemMap)
            map["requestType"] = requestType
            map["count"] = p1
            map["pois"] = list
            channel.invokeMethod("onPOISearchDone", map)
        }
    }

    override fun onGetInputtips(item: MutableList<Tip>?, p1: Int) {
        if (item == null){
            val map = mutableMapOf<String, Any>()
            map["requestType"] = requestType
            map["errMessage"] = "unknown err"
            channel.invokeMethod("onAMapSearchRequest_didFailWithError", map)
        }else {
            val map = mutableMapOf<String, Any>()
            var notNullList = item.filter {
                it.point != null
            }
            val list = notNullList.map {
                mutableMapOf<String, Any>().apply {
                    this["address"] = it.address
                    this["adCode"] = it.adcode
                    this["name"] = it.name
                    this["district"] = it.district
                    this["uid"] = it.poiID
                    this["latitude"] =it.point.latitude
                    this["longitude"] = it.point.longitude
                }
            }

            map["requestType"] = requestType
            map["count"] = p1
            map["tips"] = list
            channel.invokeMethod("onInputTipsSearchDone", map)
        }
    }

    override fun onRegeocodeSearched(item: RegeocodeResult?, p1: Int) {
        if (item == null){
            val map = mutableMapOf<String, Any>()
            map["requestType"] = requestType
            map["errMessage"] = "unknown err"
            channel.invokeMethod("onAMapSearchRequest_didFailWithError", map)
        }else {
            val map = mutableMapOf<String, Any>()
            val regeocode = mutableMapOf<String, Any>().apply {
                    this["formattedAddress"] = item.regeocodeAddress.formatAddress
                    this["addressComponent"] = mutableMapOf<String,Any>().apply {
                        this["adCode"] = item.regeocodeAddress.adCode
                        this["city"] = item.regeocodeAddress.city
                        this["cityCode"] = item.regeocodeAddress.cityCode
                        this["district"] = item.regeocodeAddress.district
                        this["province"] = item.regeocodeAddress.province
                        this["neighborhood"] = item.regeocodeAddress.neighborhood
                        this["township"] = item.regeocodeAddress.township
                        this["townCode"] = item.regeocodeAddress.towncode
                    }

                    val pois = item.regeocodeAddress.pois.map {
                        mutableMapOf<String, Any>().apply {
                            this["address"] = it.snippet
                            this["adCode"] = it.adCode
                            this["title"] = it.title
                            this["cityName"] = it.cityName
                            this["cityCode"] = it.cityCode
                            this["province"] = it.provinceName
                            this["provinceCode"] = it.provinceCode
                            this["tel"] = it.tel
                            this["poiId"] = it.poiId
                            this["businessArea"] = it.businessArea
                            this["distance"] = it.distance
                            this["adName"] = it.adName
                            this["latitude"] =it.latLonPoint.latitude
                            this["longitude"] = it.latLonPoint.longitude
                        }
                    }
                    this["pois"] = pois
                }

            map["requestType"] = requestType
            map["count"] = p1
            map["regeocode"] = regeocode
            channel.invokeMethod("onReGeocodeSearchDone", map)
        }
    }

    override fun onGeocodeSearched(item: GeocodeResult?, p1: Int) {
        if (item == null){
            val map = mutableMapOf<String, Any>()
            map["requestType"] = requestType
            map["errMessage"] = "unknown err"
            channel.invokeMethod("onAMapSearchRequest_didFailWithError", map)
        }else {
            val map = mutableMapOf<String, Any>()
            val list = item.geocodeAddressList.map {
                mutableMapOf<String, Any>().apply {
                    this["formattedAddress"] = it.formatAddress
                    this["adCode"] = it.adcode
                    this["district"] = it.district
                    this["city"] = it.city
                    this["province"] = it.province
                    this["level"] = it.level
                    this["township"] = it.township
                    this["latitude"] =it.latLonPoint.latitude
                    this["longitude"] = it.latLonPoint.longitude
                }
            }
            map["requestType"] = requestType
            map["count"] = p1
            map["geocodes"] = list
            channel.invokeMethod("onGeocodeSearchDone", map)
        }
    }

    override fun onDistanceSearched(item: DistanceResult?, p1: Int) {
        if (item == null){
            val map = mutableMapOf<String, Any>()
            map["requestType"] = requestType
            map["errMessage"] = "unknown err"
            channel.invokeMethod("onAMapSearchRequest_didFailWithError", map)
        }else {
            val map = mutableMapOf<String, Any>()
            var list = item.distanceResults.map {
                mutableMapOf<String, Any>().apply {
                    var errorInfo:String =  ""
                    if(it.errorInfo != null ){
                        errorInfo = it.errorInfo
                    }

                    this["originID"] = it.originId
                    this["destID"] = it.destId
                    this["distance"] = it.distance.toInt()
                    this["duration"] = it.duration.toInt()
                    this["info"] = errorInfo
                    this["code"] = it.errorCode
                }
            }
            map["requestType"] = requestType
            map["distanceList"] = list
            channel.invokeMethod("onDistanceSearchDone", map)
        }
    }


}